import express, { Request, Response } from 'express';
import bcrypt from 'bcryptjs';
import moment from 'moment';
import db from '../config/db.js';
import smsService from '../services/smsService.js';
import { ResultSetHeader, RowDataPacket } from 'mysql2';
import { verifyToken, generateToken, AuthRequest } from '../middleware/auth';
import { toCamelCase, toSnakeCase } from '../utils/transform';

const router = express.Router();

interface User {
  id: number;
  phone: string;
  password: string;
}

interface SmsCode {
  id: number;
  phone: string;
  code: string;
  created_at: string;
  used: boolean;
}

/**
 * @swagger
 * /users/register:
 *   post:
 *     summary: 用户注册
 *     description: 使用用户名和密码验证码注册
 *     tags:
 *       - Users
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - phone
 *               - password
 *               - code
 *             properties:
 *               phone:
 *                 type: string
 *                 description: 手机号
 *                 default: "17091266225"
 *               password:
 *                 type: string
 *                 description: 密码
 *                 default: "123123"
 *               code:
 *                 type: string
 *                 description: 验证码
 *                 default: "123123"
 *     responses:
 *       200:
 *         description: 登录成功
 *       401:
 *         description: 用户名或密码错误
 *       500:
 *         description: 服务器内部错误
 */
router.post('/register', async (req: Request, res: Response) => {
  try {
    const { phone, password, code } = req.body;

    if (!/^1[3-9]\d{9}$/.test(phone)) {
      res.status(500).json({ code: 500, message: '手机号格式不正确' });
      return
    }

    if (password.length < 6 || password.length > 20) {
      res.status(500).json({ code: 500, message: '密码长度需在6-20位之间' });
      return
    }

    const isValid = await smsService.verifyCode(phone, code);
    if (!isValid) {
      res.status(500).json({ code: 500, message: '验证码错误或已过期' });
      return
    }

    const [exists] = await db.query<RowDataPacket[]>('SELECT id FROM users WHERE phone = ?', [phone]);
    if (exists.length > 0) {
      res.status(500).json({ code: 500, message: '该手机号已注册' });
      return
    }

    const hashedPassword = await bcrypt.hash(password, 10);
    const [result] = await db.query<ResultSetHeader>(
      'INSERT INTO users (phone, password) VALUES (?, ?)',
      [phone, hashedPassword]
    );

    // 生成token
    const token = generateToken({ id: (result as ResultSetHeader).insertId, phone: phone });

    res.json(toCamelCase({
      code: 200,
      message: '注册成功',
      data: {
        user_id: (result as ResultSetHeader).insertId,
        token
      }
    }));
  } catch (err) {
    console.error('注册失败:', err);
    res.status(500).json({ code: 500, message: '注册失败，请稍后重试' });
  }
});

/**
 * @swagger
 * /users/loginPw:
 *   post:
 *     summary: 用户登录
 *     description: 使用用户名和密码登录
 *     tags:
 *       - Users
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - phone
 *               - password
 *             properties:
 *               phone:
 *                 type: string
 *                 description: 用户名
 *               password:
 *                 type: string
 *                 description: 密码
 *     responses:
 *       200:
 *         description: 登录成功
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 message:
 *                   type: string
 *                 data:
 *                   type: object
 *                   properties:
 *                     token:
 *                       type: string
 *       401:
 *         description: 用户名或密码错误
 *       500:
 *         description: 服务器内部错误
 */
router.post('/loginPw', async (req: Request, res: Response) => {
  try {
    const { phone, password } = req.body;
    console.log('[ phone, password ]-161', phone, password)

    // 查找用户
    const [users] = await db.execute<RowDataPacket[]>(
      'SELECT id, phone, password FROM users WHERE phone = ?',
      [phone]
    );
    
    if (users.length === 0) {
      res.status(401).json({ message: '用户名或密码错误' });
      return
    }

    const user = users[0];
    console.log('[ user ]-174', user)

    // 验证密码
    if (!user.password) {
      res.status(500).json({ message: '用户密码数据异常' });
      return;
    }

    const validPassword = await bcrypt.compare(password, user.password);
    if (!validPassword) {
      res.status(401).json({ message: '用户名或密码错误' });
      return;
    }

    // 生成token
    const token = generateToken({ id: user.id, phone: user.phone });
    console.log('[ token ]-188', token)
    
    // 登录成功
    res.status(200).json(toCamelCase({ 
      message: '登录成功', 
      data: {
        ...user, 
        password: undefined,
        token
      }
    }));
  } catch (error) {
    console.error('登录错误:', error);
    res.status(500).json({ message: '服务器内部错误' });
  }
});

/**
 * @swagger
 * /users/loginCode:
 *   post:
 *     summary: 验证码登录
 *     description: 使用手机号和验证码登录
 *     tags:
 *       - Users
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - phone
 *               - code
 *             properties:
 *               phone:
 *                 type: string
 *               code:
 *                 type: string
 *     responses:
 *       200:
 *         description: 登录成功
 *       400:
 *         description: 验证码错误或过期
 *       404:
 *         description: 用户不存在
 *       500:
 *         description: 服务器内部错误
 */
router.post('/loginCode', async (req: Request, res: Response) => {
  try {
    const { phone, code } = req.body;
    const isValid = await smsService.verifyCode(phone, code);
    if (!isValid) {
      res.status(500).json({ code: 500, message: '验证码错误或已过期' });
      return
    }
    // 查找用户
    const [users] = await db.execute<RowDataPacket[]>(
      'SELECT * FROM users WHERE phone = ?',
      [phone]
    );

    if (users.length === 0) {
      res.status(404).json({ message: '用户不存在' });
      return
    }

    const user = users[0];

    // 生成token
    const token = generateToken({ id: user.id, phone: user.phone });

    res.status(200).json(toCamelCase({ 
      message: '登录成功', 
      data: {
        user_id: user.id,
        token
      }
    }));
  } catch (error) {
    console.error('验证码登录错误:', error);
    res.status(500).json({ message: '服务器内部错误' });
  }
});

/**
 * @swagger
 * /users/resetPassword:
 *   post:
 *     summary: 重置密码
 *     description: 通过短信验证码重置密码
 *     tags:
 *       - Users
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - phone
 *               - code
 *               - newPassword
 *             properties:
 *               phone:
 *                 type: string
 *               code:
 *                 type: string
 *               newPassword:
 *                 type: string
 *     responses:
 *       200:
 *         description: 密码重置成功
 *       400:
 *         description: 验证码错误或过期
 *       404:
 *         description: 用户不存在
 *       500:
 *         description: 服务器内部错误
 */
router.post('/resetPassword', async (req: Request, res: Response) => {
  try {
    const { phone, code, newPassword } = req.body;

    // // 验证短信验证码
    // const [codes] = await db.execute<RowDataPacket[]>(
    //   'SELECT * FROM sms_codes WHERE phone = ? AND code = ? ORDER BY created_at DESC LIMIT 1',
    //   [phone, code]
    // );

    // if (codes.length === 0) {
    //   res.status(400).json({ message: '验证码错误' });
    //   return
    // }

    // const smsCode = codes[0];

    // // 检查验证码是否过期
    // if (moment().diff(moment(smsCode.created_at), 'minutes') > 5) {
    //   res.status(400).json({ message: '验证码已过期' });
    //   return
    // }
    const isValid = await smsService.verifyCode(phone, code);
    if (!isValid) {
      res.status(500).json({ code: 500, message: '验证码错误或已过期' });
      return
    }
    // 查找用户
    const [users] = await db.execute<RowDataPacket[]>(
      'SELECT * FROM users WHERE phone = ?',
      [phone]
    );

    if (users.length === 0) {
      res.status(404).json({ message: '用户不存在' });
      return
    }

    const user = users[0];

    // 密码加密
    const salt = await bcrypt.genSalt(10);
    const passwordHash = await bcrypt.hash(newPassword, salt);

    // 更新密码
    await db.execute(
      'UPDATE users SET password = ? WHERE id = ?',
      [passwordHash, user.id]
    );
    res.status(200).json(toCamelCase({ message: '密码重置成功' }));
  } catch (error) {
    console.error('重置密码错误:', error);
    res.status(500).json({ message: '服务器内部错误' });
  }
});

/**
 * @swagger
 * /users/info:
 *   get:
 *     summary: 获取用户信息
 *     description: 根据token获取用户基本信息
 *     tags:
 *       - Users
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: 成功获取用户信息
 *       401:
 *         description: 未授权或token无效
 *       404:
 *         description: 用户不存在
 *       500:
 *         description: 服务器内部错误
 */
router.get('/info', verifyToken, async (req: AuthRequest, res: Response) => {
  try {
    // 从token中获取用户ID
    const userId = req.user?.id;

    const [users] = await db.execute<RowDataPacket[]>(
      'SELECT id, user_name, email, phone FROM users WHERE id = ?',
      [userId]
    );

    if (users.length === 0) {
      res.status(404).json({ message: '用户不存在' });
      return
    }

    res.status(200).json(toCamelCase(users[0]));
  } catch (error) {
    console.error('获取用户信息错误:', error);
    res.status(500).json({ message: '服务器内部错误' });
  }
});

export default router;
